package com.dwusoft.banks.controller;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import utils.Constants;
import utils.SM2Utils;

import com.alibaba.fastjson.JSON;
import com.dwusoft.banks.model.TransInput;
import com.google.gson.Gson;

@Controller
@RequestMapping("/trans")
public class TransController {
	
	private final static Logger logger = LoggerFactory.getLogger(TransController.class);
	
	@RequestMapping(value = "{action}",method = RequestMethod.GET)
	public void p2pHome(ModelMap modelMap,HttpServletRequest request){
		String base = request.getContextPath();
		String fullPath = request.getScheme()+"://" + request.getServerName() +":"+ request.getServerPort() + base;
		logger.info("访问： "+fullPath);
		modelMap.addAttribute("base", base);
	}
	
	
	@RequestMapping(value = "{actionURL}",method = RequestMethod.POST)
	public String createAccount(TransInput transInput,ModelMap model,HttpServletRequest request){
		logger.info(transInput.toString());
		//1.生成请求业务对象
		logger.info("================step 1  生成请求业务对象=================");
		logger.info(request.getParameter("out_trade_no"));
		String sign = "";
		String body = req2str(request,transInput);
		logger.info("Context： "+body);
		
		//2.生成报文头
		logger.info("================step 2  生成签名=================");
		logger.info("Context： "+body);
		try {
			sign = SM2Utils.signRaw(body, transInput.getSecuNo());
			logger.info("签名值：" + sign);
		} catch (Exception e) {
			logger.error("生成签名失败");
			e.printStackTrace();
		}
	
		//3.生成密文
		logger.info("================step 3  生成密文=================");
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put(Constants.SIGN_NAME, sign);
		paramMap.put(Constants.BODY_NAME, body);
		
		String plainTxt = JSON.toJSONString(paramMap);	//待加密字符串
		logger.info("明文：" + plainTxt);
		
		String cipherTxt = "";//密文
		try {
			cipherTxt = SM2Utils.encrypt(plainTxt);
			logger.info("密文：" + cipherTxt);
		} catch (Exception e) {
			logger.error("加密失败");
			e.printStackTrace();
		}
		
		
		logger.info("================step 4 返回前台，调整资金托管平台 =================");
		model.addAttribute(Constants.CONTEXT_NAME, cipherTxt);
		model.addAttribute(Constants.PARAM_CUST_NO, transInput.getSecuNo());
		model.addAttribute(Constants.PARAM_TRANSCODE, transInput.getTransCode());

		logger.info("ServerPort:" + request.getServerPort());
		if (Constants.INTERNAL_PORT == request.getServerPort()) {
			model.addAttribute("actionURL", Constants.NET_TRADE_PLATFORM_INTERNAL_URL + request.getServletPath());
		} else if (Constants.EXTERNAL_PORT == request.getServerPort()) {
			model.addAttribute("actionURL", Constants.NET_TRADE_PLATFORM_EXTERNAL_URL + request.getServletPath());
		} else {
			model.addAttribute("actionURL", Constants.NET_TRADE_PLATFORM_URL + request.getServletPath());
		}
		logger.info("actionURL:" + (String)model.get("actionURL"));
		return "redirect";
		
//		String custNo = "3001";
//		plainTxt = "{\\\"clientNo\\\":\\\"1000008904\\\",\\\"clientName\\\":\\\"陈远勋\\\",\\\"fundAcc\\\":\\\"9595000008904002\\\",\\\"secuAcc\\\":\\\"100090\\\",\\\"idType\\\":\\\"1\\\",\\\"idCode\\\":\\\"150522198801312018\\\",\\\"mobile\\\":\\\"13656668135\\\",\\\"email\\\":\\\"999@163.com\\\",\\\"secuNo\\\":\\\"3001\\\",\\\"secuName\\\":\\\"\\\",\\\"openDate\\\":\\\"20150925\\\",\\\"bindFlag\\\":\\\"\\\",\\\"bindFlagName\\\":\\\"\\\",\\\"status\\\":\\\"0\\\",\\\"statusName\\\":\\\"正常\\\",\\\"balance\\\":\\\"4.50\\\",\\\"useBala\\\":\\\"4.50\\\",\\\"cashBala\\\":\\\"4.50\\\",\\\"reprName\\\":\\\"\\\",\\\"reprIdType\\\":\\\"\\\",\\\"reprIdCode\\\":\\\"\\\",\\\"actorName\\\":\\\"\\\",\\\"actorIdType\\\":\\\"\\\",\\\"actorIdCode\\\":\\\"\\\",\\\"summary\\\":\\\"\\\",\\\"flag1\\\":\\\"0\\\",\\\"flag2\\\":\\\"\\\",\\\"transOutput\\\":{\\\"orderId\\\":\\\"jimbox20151022162943\\\",\\\"secuNo\\\":\\\"3001\\\",\\\"usrId\\\":\\\"jmbox0001\\\",\\\"fundAcc\\\":\\\"9595000008904002\\\",\\\"transCode\\\":\\\"CNP_Q000001\\\",\\\"outputTime\\\":\\\"20151022162948\\\",\\\"type\\\":\\\"S\\\",\\\"code\\\":\\\"0000\\\",\\\"message\\\":\\\"交易成功\\\",\\\"reserve2\\\":\\\"\\\"}}\",\"retCode\":\"0000\"}";
//		String actionUrl = "http://localhost:8080/netTradeGate/cipher.html";
//		model.addAttribute("custNo", custNo);
//		model.addAttribute("plainTxt", plainTxt);
//		model.addAttribute("actionURL", actionUrl);
//		
//		return "redirect3";
	}

	private String req2str(HttpServletRequest request, TransInput transInput)
	{
		Map<String, Object> retMap = new HashMap<String, Object>();
		Map<String, String[]> params = request.getParameterMap();
		Field[] fields = TransInput.class.getDeclaredFields();
		for (String key : params.keySet())
		{
			Field field;
			try
			{
				if (hasField(fields, key)) {
					field = TransInput.class.getDeclaredField(key);
					if (key.equalsIgnoreCase(field.getName()))
					{
						// System.out.println("+++++++"+field.getName());
						continue;
					}
				}
			}
			catch (SecurityException e)
			{
				e.printStackTrace();
			}
			catch (NoSuchFieldException e)
			{
//				e.printStackTrace();
			}

			String value = params.get(key)[0];
			if (value.length() == 0 || "".equals(value))
			{
				continue;
			}
			retMap.put(key, value);

		}

		SimpleDateFormat sf1 = new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat sf2 = new SimpleDateFormat("hhmmss");

		transInput.setTransDate(sf1.format(new Date()));
		transInput.setTransTime(sf2.format(new Date()));

		retMap.put("transInput", transInput);

		Gson gson = new Gson();

		return gson.toJson(retMap);

		// return JSON.toJSONString(retMap);
	}
	
	/**
	 * 判断fields中是否有指定名称的field
	 * @param fields
	 * @param name
	 * @return
	 */
	private boolean hasField(Field[] fields, String name) {
		for (Field field : fields) {
			if (name.equals(field.getName())) {
				return true;
			}
		}
		return false;
	}

}
